package cn.itcast.zt.controller;

import cn.itcast.zt.redis.AquiredLockWorker;
import cn.itcast.zt.redis.lock.RedisLocker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * Created by zhangtian on 2017/5/2.
 */
@RestController
@RequestMapping(value = "/")
public class TestRedisLockController {
    @Autowired
    private RedisLocker distributedLocker ;

    @GetMapping("redLock")
    public String testRedLock() throws Exception {
        CountDownLatch startSignal = new CountDownLatch(1) ;
        CountDownLatch doneSignal = new CountDownLatch(5) ;

        for(int i = 0; i < 5 ; i++) {
            new Thread(new Worker(startSignal, doneSignal)).start() ;
        }

        startSignal.countDown();
        doneSignal.await();
        System.out.println("All processors done. Shutdown connection");

        return "redLock" ;
    }

    class Worker implements Runnable{
        private final CountDownLatch startSignal ;
        private final CountDownLatch doneSignal ;

        Worker(CountDownLatch startSignal, CountDownLatch doneSignal){
            this.startSignal = startSignal ;
            this.doneSignal = doneSignal ;
        }

        @Override
        public void run() {
            try {
                startSignal.await();
                distributedLocker.lock("testLock", new AquiredLockWorker<Object>(){
                    @Override
                    public Object invokeAfterLockAquire() throws Exception {
                        doTask() ;
                        return null;
                    }
                }) ;
            }catch (Exception e){

            }
        }

        void doTask() {
            System.out.println(Thread.currentThread().getName() + " start");
            Random random = new Random();
            int _int = random.nextInt(200);
            System.out.println(Thread.currentThread().getName() + " sleep " + _int + "millis");
            try {
                Thread.sleep(_int);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " end");
            doneSignal.countDown();
        }
    }
}
